using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using MacomberMap.Common.Components;
using MacomberMap.Common.User_Interfaces.Components;
using System.Drawing;
using System.ComponentModel;
using System.Xml;
using MacomberMap.Common.Database_Interface;

namespace MacomberMap.Common.User_Interfaces.One_Lines.Elements
{
    /// <summary>
    /// This class holds the poke point information
    /// </summary>
    public class MM_OneLine_PokePoint: MM_OneLine_Element
    {
        #region Variable declarations
        /// <summary>Whether the poke point is a jumper</summary>
        private bool _IsJumper = false;

        /// <summary>Whether the poke point is a jumper</summary>
        [Category("Display"), Description("Whether the poke point is a jumper")]
        public bool IsJumper
        {
            get { return _IsJumper; }
            set { _IsJumper = value; IsVisible = _IsVisible; }
        }



        /// <summary>Whether the box should be drawn for this poke point</summary>
        private bool _IsVisible = true;

        /// <summary>Whether the box should be drawn for this poke point</summary>        
        [Category("Display"), Description("Whether the box should be drawn for this poke point")]
        public bool IsVisible
        {
            get { return _IsVisible; }
            set
            {
                _IsVisible = value;
                Point OldCenter = CenterRect(Bounds);

                if (this is MM_OneLine_PricingVector)
                { }
                else if (!value)                
                    this.Size = new Size(4, 4);                                    
                else if (!_IsJumper)
                    this.Size = new Size(8, 8);
                else
                    UpdateSize(35, 11, enumOrientations.Horizontal);

            }
        }

        /// <summary>The node to which the node is connected</summary>
        public MM_OneLine_Node BaseNode;       
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize a new poke point with just display parameters
        /// </summary>
        /// <param name="DisplayParameters"></param>
        public MM_OneLine_PokePoint(MM_OneLine_Display DisplayParameters)
            : base(DisplayParameters)
        { }

        /// <summary>
        /// Initialize a poke point with no custom parameters
        /// </summary>
        /// <param name="OwnerNode"></param>
        /// <param name="DisplayParameters"></param>
        /// <param name="Orientation"></param>
        public MM_OneLine_PokePoint(MM_Element OwnerNode, MM_OneLine_Display DisplayParameters, MM_OneLine_Element.enumOrientations Orientation)
            : base(OwnerNode, DisplayParameters, Orientation)
        { }

        /// <summary>
        /// Initialize a poke point with a rectangle, for a jumper
        /// </summary>
        /// <param name="OwnerNode"></param>
        /// <param name="DisplayParameters"></param>
        /// <param name="BaseNode">The node that owns this poke point</param>
        /// <param name="Orientation">The orientation of the poke point</param>
        /// <param name="IsJumper">Whether the poke point is a jumper</param>
        /// <param name="IsVisible">whether the poke point is visible</param>
        public MM_OneLine_PokePoint(MM_Element OwnerNode, MM_OneLine_Node BaseNode, MM_OneLine_Display DisplayParameters, MM_OneLine_Element.enumOrientations Orientation, bool IsJumper, bool IsVisible)
            : base(OwnerNode, DisplayParameters, Orientation)
        {
            this.BaseNode = BaseNode;
            this.IsJumper = IsJumper;
            this.IsVisible = IsVisible;
            if (BaseNode != null)
                this.rdfID = BaseNode.rdfID;
        }

        /// <summary>
        /// Initialize a new poke point by XML configuration.
        /// </summary>
        /// <param name="ElemConfig"></param>
        /// <param name="DisplayParameters"></param>
        /// <param name="DbConnection"></param>
        public MM_OneLine_PokePoint(XmlElement ElemConfig, MM_OneLine_Display DisplayParameters, MM_Database DbConnection)
            : base(ElemConfig, DisplayParameters, DbConnection)
        {
        }
        #endregion

        #region Rendering
        /// <summary>
        /// Draw the poke point
        /// </summary>
        /// <param name="g"></param>
        public override void DrawImage(Graphics g)
        {
            Point CenterBounds = CenterRect(DisplayRectangle);
            using (Pen pn = new Pen(BaseElement == null || BaseElement.KVLevel == null ? Color.Red : BaseElement.KVLevel.Energized.ForeColor))
                if (IsJumper && (Orientation == enumOrientations.Horizontal || Orientation == enumOrientations.Left || Orientation == enumOrientations.Right || Orientation == enumOrientations.Unknown))
                    using (SolidBrush BackBrush = new SolidBrush(BackColor))
                    {
                        int JumperSize = (int)Math.Ceiling((float)Width / 4f);
                        g.FillRectangle(BackBrush, JumperSize, CenterBounds.Y - 1, Width - (JumperSize * 2), Height - 1);
                        g.DrawArc(pn, JumperSize, 1, Width  - (JumperSize * 2), Height - 2, 0, 180);
                        g.DrawLine(pn, 0, CenterBounds.Y, JumperSize, CenterBounds.Y);
                        g.DrawLine(pn, Width + 1 - JumperSize, CenterBounds.Y, Width - 1, CenterBounds.Y);
                    }
                else if (IsJumper && (Orientation == enumOrientations.Vertical || Orientation == enumOrientations.Up || Orientation == enumOrientations.Down))
                    using (SolidBrush BackBrush = new SolidBrush(BackColor))
                    {
                        int JumperSize = (int)Math.Ceiling((float)Height / 4f);
                        
                        //using (Pen BackPen = new Pen(BackColor, 3))
                        //    g.DrawArc(BackPen, 0, JumperSize, Width - 1, Height - (JumperSize * 2), 90, 180);
                        g.FillRectangle(BackBrush, 0, JumperSize, Width - 1, Height - (JumperSize * 2));
                        
                        
                        g.DrawArc(pn, 0, JumperSize, Width - 1, Height - (JumperSize * 2), 90, 180);
                        g.DrawLine(pn, CenterBounds.X, 0, CenterBounds.X, JumperSize);
                        g.DrawLine(pn, CenterBounds.X, Height + 1 - JumperSize, CenterBounds.X, Height - 1);
                    }
                else
                    g.FillRectangle(pn.Brush, DisplayRectangle);
        }

        
        /// <summary>
        /// Report the information on the poke point
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            String ThisBase = BaseElement == null ? "Unknown element" : BaseElement.ToString();
            if (this is MM_OneLine_PricingVector)
                return String.Format("{0} ({1},{2})-({3},{4}) to {5}", "PV ", Left, Top, Right, Bottom, ThisBase);                                              
            else if (this is MM_OneLine_Node)
                if (this.BaseElement != null && (this.BaseElement as MM_Node).BusbarSection != null)
                    return String.Format("{0} ({1},{2})-({3},{4}) to {5}", "BusbarSection ", Left, Top, Right, Bottom, (BaseElement as MM_Node).BusbarSection.ToString() + " / " + ThisBase);            
                else
                    return String.Format("{0} ({1},{2})-({3},{4}) to {5}", "Node ", Left, Top, Right, Bottom, ThisBase);            
            else if (IsJumper)
                return String.Format("{0} ({1},{2})-({3},{4}) to {5}",  "Jumper ", Left, Top, Right, Bottom, BaseElement.ToString());
            else if (!IsVisible)
                return String.Format("{0} ({1},{2})-({3},{4}) to {5}", "Invisible PokePoint ", Left, Top, Right, Bottom, BaseElement.ToString());
            else
                return String.Format("{0} ({1},{2})-({3},{4}) to {5}", "PokePoint ", Left, Top, Right, Bottom, BaseElement.ToString());
        }
        #endregion
    }
}
